using System;
using System.Net.NetworkInformation;
using NLog;

namespace LDNS.Monitor
{
    /// <summary>
    /// 网络变化监控服务类
    /// 负责监控网络状态变化，并在网络变化时确保本地DNS服务器优先
    /// 作者：huobing
    /// </summary>
    public class NetworkMonitorService : IDisposable
    {
        private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
        private bool _started = false;
        private bool _disposed = false;

        /// <summary>
        /// 网络状态变化事件
        /// </summary>
        public event EventHandler<EventArgs>? NetworkStateChanged;

        /// <summary>
        /// 启动网络监控服务
        /// </summary>
        public void Start()
        {
            if (_started) return;
            _started = true;

            try
            {
                // 订阅网络变化事件
                NetworkChange.NetworkAddressChanged += OnNetworkChanged;
                NetworkChange.NetworkAvailabilityChanged += OnNetworkAvailabilityChanged;

                _logger.Info("网络监控服务已启动");
                
                // 启动时立即检查一次网络状态
                CheckAndEnsureDnsSettings();
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "启动网络监控服务时发生异常");
                Stop();
            }
        }

        /// <summary>
        /// 停止网络监控服务
        /// </summary>
        public void Stop()
        {
            if (!_started) return;
            _started = false;

            try
            {
                // 取消订阅网络变化事件
                NetworkChange.NetworkAddressChanged -= OnNetworkChanged;
                NetworkChange.NetworkAvailabilityChanged -= OnNetworkAvailabilityChanged;

                _logger.Info("网络监控服务已停止");
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "停止网络监控服务时发生异常");
            }
        }

        /// <summary>
        /// 网络地址变化事件处理程序
        /// </summary>
        /// <param name="sender">事件源</param>
        /// <param name="e">事件参数</param>
        private void OnNetworkChanged(object? sender, EventArgs e)
        {
            _logger.Info("检测到网络地址变化");
            CheckAndEnsureDnsSettings();
            NetworkStateChanged?.Invoke(this, EventArgs.Empty);
        }

        /// <summary>
        /// 网络可用性变化事件处理程序
        /// </summary>
        /// <param name="sender">事件源</param>
        /// <param name="e">事件参数</param>
        private void OnNetworkAvailabilityChanged(object? sender, NetworkAvailabilityEventArgs e)
        {
            _logger.Info($"检测到网络可用性变化: {(e.IsAvailable ? "可用" : "不可用")}");
            CheckAndEnsureDnsSettings();
            NetworkStateChanged?.Invoke(this, EventArgs.Empty);
        }

        /// <summary>
        /// 检查并确保本地DNS服务器优先
        /// </summary>
        private void CheckAndEnsureDnsSettings()
        {
            try
            {
                _logger.Debug("检查并确保127.0.0.1作为首位DNS服务器");
                
                // 调用WindowsDnsManager的EnsureLocalhostPrimaryDns方法
                bool success = WindowsDnsManager.EnsureLocalhostPrimaryDns();
                
                if (success)
                {
                    _logger.Debug("DNS设置检查完成");
                }
                else
                {
                    _logger.Warn("DNS设置检查失败，请确保程序以管理员权限运行");
                }
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "确保本地DNS优先时发生错误");
            }
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            if (_disposed) return;
            
            Stop();
            _disposed = true;
        }
    }
}